#!/usr/bin/perl

use lib::abs qw( base_lib lib );
use JIP::ToolSet; # load my commonly-used modules in a single import

use File::Spec::Functions qw( catfile ); # CPAN modules
use FindBin qw( $RealBin );              #
use File::Copy qw( move );               #
use English qw( -no_match_vars );        #
use Carp qw( croak );                    #

use Configurator;                # base lib
use Log;                         #
use JIP::Utils qw( getLogName ); #
use Proc::Lock;                  #

use DB::Schema;                              # searcher custom modules
use Build::CommandCreator;                   #
use Filesystem qw( getFilterOutputListing ); #

#-- init settings --------------------------------------------------------------
my $conf = Configurator->new( conf => 'robo_conf.pm' )->getSettings;

#-- init log -------------------------------------------------------------------
our $log = Log->new(
    log_file  => catfile( $conf->build->log_dir, getLogName() ),
    log_level => $conf->build->log_level,
);

#-- signal handlers ------------------------------------------------------------
require( catfile( $RealBin, 'signal_handlers.pl' ) );

#-- setup lock -----------------------------------------------------------------
$log->Note('setup lock');

my $process = Proc::Lock->new( lock_file => $conf->build->lock_file );

$process->lock;

#-- orm handle -----------------------------------------------------------------
my $orm = DB::Schema->connect(
    $conf->sql->dsn,
    $conf->sql->user,
    $conf->sql->pass,
);

$orm->storage->debug( $conf->sql->isDebug );

#-- getting input files --------------------------------------------------------
$log->Note('getting input files...');
$log->Note('moving files from INPUT_DIR to SCRATCH_DIR:');

foreach my $eachFile ( getFilterOutputListing $conf->build->input_dir ) {
    $log->Note( $eachFile->name );

    move( $eachFile->relativePath, $conf->build->scratch_dir )
        or croak 'cannot move '. $eachFile->name .' to SCRATCH_DIR';
}

#-- build ----------------------------------------------------------------------
my @buildSteps = qw(
    DropTmpTables
    MakeTmpTables
    CopyFromTablesToTmpTables
    SetAgeing
    LoadContent
    OptimizeTables
    MoveTables
    UpdateStatistic
);

$log->Note('fire started build loop');

foreach my $eachBuildStep ( @buildSteps ) {
    # the Command design pattern
    my $command = Build::CommandCreator->create(
        $eachBuildStep,
        {
            orm    => $orm,
            log    => $log,
            config => $conf,
        },
    );

    $command->execute;
}

#-- finalyze -------------------------------------------------------------------
$log->Note('-- finalyze -----------------------------------------------------');

$log->Note('cleaning SCRATCH_DIR...');

foreach my $eachFile ( getFilterOutputListing $conf->build->scratch_dir ) {
    unlink $eachFile->relativePath
        or croak 'cannot unlink '. $eachFile->relativePath .': '. $OS_ERROR;
}

$log->Note('unset lock...') and $process->unlock;

$log->Note('exiting');

#-- end ------------------------------------------------------------------------
